package com.itheima.project.face.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.itheima.project.adapter.SmsSignAdapter;
import com.itheima.project.basic.ResponseWrap;
import com.itheima.project.constant.sms.SmsCacheConstant;
import com.itheima.project.core.enums.sms.SmsSignEnum;
import com.itheima.project.exception.ProjectException;
import com.itheima.project.face.SmsSignFace;
import com.itheima.project.feign.FileFeign;
import com.itheima.project.pojo.SmsSign;
import com.itheima.project.service.ISmsSignService;
import com.itheima.project.utils.BeanConv;
import com.itheima.project.utils.EmptyUtil;
import com.itheima.project.utils.ExceptionsUtil;
import com.itheima.project.vo.file.FileVo;
import com.itheima.project.vo.sms.SmsSignVo;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName SmsSignFaceImpl.java
 * @Description TODO
 */
@Slf4j
@Component
public class SmsSignFaceImpl implements SmsSignFace {

    @Autowired
    SmsSignAdapter smsSignAdapter;

    @Autowired
    ISmsSignService smsSignService;

    @Autowired
    FileFeign fileFeign;

    @Override
    @Cacheable(value = SmsCacheConstant.PAGE_SIGN,key ="#pageNum+'-'+#pageSize+'-'+#smsSignVo.hashCode()")
    public Page<SmsSignVo> findSmsSignVoPage(SmsSignVo smsSignVo,
                                             int pageNum,
                                             int pageSize) throws ProjectException {
        try {
            //查询Page<SmsSignVo>图片分页
            Page<SmsSign> page = smsSignService.findSmsSignVoPage(smsSignVo, pageNum, pageSize);
            //转化Page<SmsSignVo>为Page<SmsSignVo>
            Page<SmsSignVo> pageVo = BeanConv.toPage(page,SmsSignVo.class);
            List<SmsSignVo> smsSignVoVoList = pageVo.getRecords();
            for (SmsSignVo signVo : smsSignVoVoList) {
                ResponseWrap<List<FileVo>> fileVoResponseWrap = fileFeign.findFileVoByBusinessId(
                        FileVo.builder().businessId(signVo.getId()).build());
                List<FileVo> fileVos = fileVoResponseWrap.getDatas();
                LinkedList<FileVo> linkedList = new LinkedList<>();
                if (!EmptyUtil.isNullOrEmpty(fileVos)){
                    linkedList.addAll(fileVos);
                }
                signVo.setFileVos(linkedList);
            }
            pageVo.setRecords(smsSignVoVoList);
            //返回结果
            return pageVo;
        } catch (Exception e) {
            log.error("查询签名列表异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(SmsSignEnum.PAGE_FAIL);
        }
    }

    @Override
    @GlobalTransactional
    @Caching(evict = {@CacheEvict(value = SmsCacheConstant.PAGE_SIGN,allEntries = true),
            @CacheEvict(value = SmsCacheConstant.SIGN_LIST,allEntries = true)},
            put={@CachePut(value =SmsCacheConstant.PREFIX_SIGN,key = "#result.id")})
    public SmsSignVo addSmsSign(SmsSignVo smsSignVo) throws ProjectException{
        try {
            LinkedList<FileVo> fileVos = smsSignVo.getFileVos();
            StringBuffer base64Image =new StringBuffer();
            StringBuffer suffix =new StringBuffer();
            for (FileVo fileVo : fileVos) {
                ResponseWrap<FileVo> fileVoResponseWrap = fileFeign.downLoad(fileVo.getId());
                FileVo fileVoHandler = fileVoResponseWrap.getDatas();
                if (!EmptyUtil.isNullOrEmpty(fileVoHandler)){
                    base64Image.append(fileVoHandler.getBase64Image()).append("@");
                    suffix.append(fileVoHandler.getSuffix()).append("@");
                }
            }
            if (!EmptyUtil.isNullOrEmpty(base64Image)&&!EmptyUtil.isNullOrEmpty(suffix)){
                String base64ImageString = base64Image.toString();
                String suffixString = suffix.toString();
                smsSignVo.setProofImage(base64ImageString.substring(0,base64ImageString.length()-1));
                smsSignVo.setProofType(suffixString.substring(0,suffixString.length()-1));
            }
            SmsSignVo smsSignVoHandler = smsSignAdapter.addSmsSign(smsSignVo);
            if (!EmptyUtil.isNullOrEmpty(smsSignVoHandler)){
                List<FileVo> fileVosHandler = fileVos.stream().map(n -> new FileVo(
                        n.getId(),
                        smsSignVoHandler.getId())).collect(Collectors.toList());
                fileFeign.bindBatchBusinessId(Lists.newArrayList(fileVosHandler));
            }
            return smsSignVo;
        } catch (Exception e) {
            log.error("添加签名异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(SmsSignEnum.CREATE_FAIL);
        }
    }

    @Override
    @GlobalTransactional
    @Caching(evict = {@CacheEvict(value = SmsCacheConstant.PAGE_SIGN,allEntries = true),
            @CacheEvict(value = SmsCacheConstant.SIGN_LIST,allEntries = true),
            @CacheEvict(value = SmsCacheConstant.PREFIX_SIGN,allEntries = true)})
    public Boolean deleteSmsSign(String[] checkedIds)throws ProjectException {
        try {
            Boolean flag = smsSignAdapter.deleteSmsSign(checkedIds);
            if (flag){
                fileFeign.deleteFileVoByBusinessId(FileVo.builder().checkedIds(checkedIds).build());
            }
            return flag;
        } catch (Exception e) {
            log.error("删除签名异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(SmsSignEnum.DELETE_FAIL);
        }
    }

    @Override
    @GlobalTransactional
    @Caching(evict = {@CacheEvict(value = SmsCacheConstant.PAGE_SIGN,allEntries = true),
            @CacheEvict(value = SmsCacheConstant.SIGN_LIST,allEntries = true),
            @CacheEvict(value = SmsCacheConstant.PREFIX_SIGN,key = "#smsSignVo.id")})
    public SmsSignVo modifySmsSign(SmsSignVo smsSignVo)throws ProjectException {
        try {
            LinkedList<FileVo> fileVos = smsSignVo.getFileVos();
            StringBuffer base64Image =new StringBuffer();
            StringBuffer suffix =new StringBuffer();
            for (FileVo fileVo : fileVos) {
                ResponseWrap<FileVo> fileVoResponseWrap = fileFeign.downLoad(fileVo.getId());
                FileVo fileVoHandler = fileVoResponseWrap.getDatas();
                if (!EmptyUtil.isNullOrEmpty(fileVoHandler)){
                    base64Image.append(fileVoHandler.getBase64Image()).append("@");
                    suffix.append(fileVoHandler.getSuffix()).append("@");
                }
            }
            if (!EmptyUtil.isNullOrEmpty(base64Image)&&!EmptyUtil.isNullOrEmpty(suffix)){
                String base64ImageString = base64Image.toString();
                String suffixString = suffix.toString();
                smsSignVo.setProofImage(base64ImageString.substring(0,base64ImageString.length()-1));
                smsSignVo.setProofType(suffixString.substring(0,suffixString.length()-1));
            }
            SmsSignVo smsSignVoHandler = smsSignAdapter.modifySmsSign(smsSignVo);
            if (!EmptyUtil.isNullOrEmpty(smsSignVoHandler)){
                String[] ids = new String[]{String.valueOf(smsSignVo.getId())};
                fileFeign.deleteFileVoByBusinessId(FileVo.builder().checkedIds(ids).build());
                List<FileVo> fileVosHandler = fileVos.stream().map(n -> new FileVo(
                        n.getId(),
                        smsSignVo.getId())).collect(Collectors.toList());
                fileFeign.bindBatchBusinessId(Lists.newArrayList(fileVosHandler));
            }
            return smsSignVo;
        } catch (Exception e) {
            log.error("修改签名异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(SmsSignEnum.UPDATE_FAIL);
        }
    }

    @Override
    @GlobalTransactional
    @Caching(evict = {@CacheEvict(value = SmsCacheConstant.PAGE_SIGN,allEntries = true),
            @CacheEvict(value = SmsCacheConstant.SIGN_LIST,allEntries = true),
            @CacheEvict(value = SmsCacheConstant.PREFIX_SIGN,key = "#smsSignVo.id")})
    public SmsSignVo updateSmsSignEnableFlag(SmsSignVo smsSignVo) throws ProjectException {
        try {
            boolean flag = smsSignService.updateById(BeanConv.toBean(smsSignVo, SmsSign.class));
            if (flag){
                return smsSignVo;
            }
        } catch (Exception e) {
            log.error("修改签名状态异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(SmsSignEnum.UPDATE_FAIL);
        }
        return null;
    }

    @Override
    @Cacheable(value =SmsCacheConstant.PREFIX_SIGN,key = "#smsSignVo.id")
    @GlobalTransactional
    public SmsSignVo querySmsSign(SmsSignVo smsSignVo) throws ProjectException{
        try {
            return smsSignAdapter.querySmsSign(smsSignVo);
        } catch (Exception e) {
            log.error("查询签名状态异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(SmsSignEnum.SELECT_FAIL);
        }
    }

    @Override
    @Cacheable(value =SmsCacheConstant.SIGN_LIST)
    public List<SmsSignVo> findSmsSignVoList()throws ProjectException {
        try {
            return BeanConv.toBeanList(smsSignService.findSmsSignVoList(), SmsSignVo.class);
        } catch (Exception e) {
            log.error("查找所有通道异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(SmsSignEnum.SELECT_FAIL);
        }
    }
}
